package com.yy.young.common.util;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.Map.Entry;

import com.yy.young.base.util.GlobalConstants;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 可优化为池处理
 */
public class HttpClientHelper {
	
	private static Logger logger = LoggerFactory.getLogger(HttpClientHelper.class);
	
	private static final int DEFAULT_CONNECT_TIMEOUT = 300000;
	private static final int DEFAULT_READ_TIMEOUT = 300000;
	
	private static final int NORMAT_CONNECT_TIMEOUT = 10000;
	private static final int NORMAT_READ_TIMEOUT = 10000;
	
	/**
	 * 发送数据,采用默认的超时时间
	 * @param url
	 * @param data
	 * @return
	 * @throws MalformedURLException
	 * @return String
	 * @throws
	 */
	public static String send(String url,String data,Map<String,String> paramMap){
		return sendData(url, data,paramMap,NORMAT_CONNECT_TIMEOUT, NORMAT_READ_TIMEOUT);
	}
	
	/**
	 * 发送数据,定制超时时间
	 * @param url
	 * @param data
	 * @param connectTimeout
	 * @param readTimeOut
	 * @return
	 * @throws MalformedURLException
	 * @return String
	 * @throws
	 */
	public static String send(String url,String data,int connectTimeout,int readTimeOut,Map<String,String> paramMap){
		if(connectTimeout==0)connectTimeout=DEFAULT_CONNECT_TIMEOUT;
		if(readTimeOut==0)readTimeOut=DEFAULT_CONNECT_TIMEOUT;
		return sendData(url, data,paramMap,connectTimeout,readTimeOut);
	}
	
	/**
	 * 发送过程 
	 * @param url
	 * @param data
	 * @param connectTimeout
	 * @param readTimeOut
	 * @return
	 * @throws MalformedURLException
	 * @return String
	 * @throws
	 */
	private static String sendData(String url,String data,Map<String,String> paramMap,int connectTimeout,int readTimeOut){
		HttpURLConnection httpCon = null;
		try {
			URL connUrl  = new URL(url);
			httpCon = (HttpURLConnection) connUrl.openConnection();
			httpCon.setConnectTimeout(connectTimeout);
			httpCon.setReadTimeout(readTimeOut);
			httpCon.setDoOutput(true);
			httpCon.setDoInput(true);
			httpCon.setRequestMethod("POST");
			httpCon.setUseCaches(false);
			httpCon.setAllowUserInteraction(true);
			httpCon.setRequestProperty("Content-Type", "text/json; charset="+ GlobalConstants.CHARSET);
			//httpCon.setConnectTimeout(100000);
			//httpCon.setReadTimeout(100000);
			if(paramMap!=null){
				for(Entry<String,String> entry : paramMap.entrySet()){
					httpCon.setRequestProperty(entry.getKey(), entry.getValue());
				}
			}
			httpCon.setRequestProperty("sf","1");
			httpCon.connect();
			BufferedWriter out = null;
			OutputStream os = null;
			OutputStreamWriter osw = null;
			try {
				os = httpCon.getOutputStream();
				osw = new OutputStreamWriter(os, GlobalConstants.CHARSET);
				out = new BufferedWriter(osw);
				out.write(data);
				out.flush();
			} finally {
				IOUtils.closeQuietly(out);
				IOUtils.closeQuietly(osw);
				IOUtils.closeQuietly(os);
			}
			int rscode = httpCon.getResponseCode();
			if (rscode == 200)return readRequestData(httpCon.getInputStream());
			logger.error("HTTP请求没有正确返回,状态["+rscode+"]");
		}catch(Exception e){
			logger.error("HTTP请求异常",e);
		}finally {
			try{
				if (httpCon != null)httpCon.disconnect();
			}catch(Exception e){
				logger.error("关闭HTTP请求异常",e);
			}
		}
		return null;
	}
	
	/**
	 * 获取流信息
	 * @param url
	 * @return
	 * @return InputStream
	 * @throws
	 */
	public static byte[] getData(String url){
		HttpURLConnection httpCon = null;
		InputStream is = null;
		try {
			URL connUrl  = new URL(url);
			httpCon = (HttpURLConnection) connUrl.openConnection();
			httpCon.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT);
			httpCon.setReadTimeout(DEFAULT_READ_TIMEOUT);
			httpCon = (HttpURLConnection)connUrl.openConnection();
			httpCon.connect();
			is = httpCon.getInputStream();
			return convertStreamToByte(is);
		}catch(Exception e){
			logger.error("HTTP请求异常",e);
		}finally {
			IOUtils.closeQuietly(is);
			try{
				if (httpCon != null)httpCon.disconnect();
			}catch(Exception e){
				logger.error("关闭HTTP请求异常",e);
			}
		}
		return null;
	}
	
	/**
	 * 转换流到字节数组
	 * @param inStream
	 * @return
	 * @throws IOException
	 */
	public static byte[] convertStreamToByte(InputStream inStream) throws IOException {
		if(inStream!=null){
			ByteArrayOutputStream swapStream = null;
			try{
				swapStream = new ByteArrayOutputStream();
				byte[] buff = new byte[1024];
				int len = -1;  
		        while ((len = inStream.read(buff)) != -1) {  
		        	swapStream.write(buff, 0, len);  
		        }
		        return swapStream.toByteArray();
			}finally{
				IOUtils.closeQuietly(swapStream);
				IOUtils.closeQuietly(inStream);
			}
		}
		return null;
	}
	
	/**
	 * 读取request中的数据
	 * @param is
	 * @return
	 * @throws Exception
	 * @return String
	 * @throws
	 */
	private static String readRequestData(InputStream is){
		StringBuffer sb = new StringBuffer();
		BufferedReader br =null;
		InputStreamReader isr = null;
		try {
			isr = new InputStreamReader(is,GlobalConstants.CHARSET);
			br = new BufferedReader(isr);
			String str = null;
			while ((str = br.readLine()) != null) {
				sb.append(str);
			}
			return sb.toString();
		} catch (Exception ioe) {
			logger.error("读取HTTP请求的返回消息异常", ioe);
		}finally{
			IOUtils.closeQuietly(br);
			IOUtils.closeQuietly(isr);
			IOUtils.closeQuietly(is);
		}
		return null;
	}
	/**
	 * 根据url地址下载文件
	 * @param url
	 */
	public InputStream download(String url){
		try {
			URL urlPath = new URL(url);
			HttpURLConnection conn = (HttpURLConnection) urlPath.openConnection();
			conn.setDoInput(true);
			conn.setDoOutput(true);
			conn.connect();
			
			int resCode = conn.getResponseCode();
			if(resCode==HttpURLConnection.HTTP_OK){
				InputStream is = conn.getInputStream();
				return is;
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	public static String postData(String urlPath, String data){
		try {
			URL url = new URL(urlPath);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setDoInput(true);
			conn.setDoOutput(true);
			conn.setUseCaches(false);
			conn.setReadTimeout(50000);
			conn.setConnectTimeout(50000);
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
			OutputStream os = conn.getOutputStream();
			os.write(data.getBytes());
			os.flush();
			os.close();
			
			conn.connect();
			int resCode = conn.getResponseCode();
			if(resCode==HttpURLConnection.HTTP_OK){
				StringBuilder sbData = new StringBuilder();
				InputStream is = conn.getInputStream();
				BufferedInputStream bis = new BufferedInputStream(is);
				int len = 8192;
				byte[] buf = new byte[len];
				int byteRead = 0;
				String encode = GlobalConstants.CHARSET;
				while((byteRead = bis.read(buf, 0, len))!=-1){
					sbData.append(new String(buf, 0, byteRead, encode));
				}
				bis.close();
				is.close();
				return sbData.toString();
			}else{
				return "error";
			}
		} catch (IOException e) {
			e.printStackTrace();
			return "error";
		}
	}
}
